///\file sizor.hh
///\brief contient les spécifications de la classe CUDA::Sizor
///\author { V.Allombert, A.Blanchard, A.Carteron, V.Pelletier } 

#ifndef _SIZOR
#define _SIZOR

#include <list>
#include "image.hh"
#include "matrix.hh"
#include <iterator>
#include <iostream>

//FAIT A LA COMPILATION !!!!
#define MPS 15
#define MAXMEM 1000000

namespace CUDA{

  ///\struct coord_data
  ///\brief coordonnées définissant les bords d'un bloc image
  struct coord_data{
    unsigned int bxi; ///< debut de coordonnées en x
    unsigned int byi; ///< debut de coordonnées en y
    unsigned int byo;
    unsigned int bxo;
    unsigned int wblock_out; ///<
    unsigned int hblock_out; ///<
    unsigned int wblock_in;
    unsigned int hblock_in;
  };

  enum { IN , OUT };

  ///\class Sizor
  ///\brief Classe de découpage d'image
  class Sizor{
  private:
    std::list<coord_data> block_lst; ///< Liste des blocks
    std::list<coord_data>::iterator it; ///< Iterateur sur la position du prochaine élément à traiter
    unsigned int block_size;
    unsigned int wblock_in;
    unsigned int hblock_in;
    unsigned int wblockmax_out;
    unsigned int hblockmax_out;

  public:

    ///\brief Constructeur
    ///construit un objet de découpe d'image
    ///\param i image à découper
    ///\param m matrix de convolution
    Sizor(const Image &i, const Matrix<char> &m);

    ///\brief récupérer un chunk
    ///\return les données du chunk
    inline coord_data next(){
      std::cout<<"NEXT\n";
      return (*it++);
    }
    
    ///\brief Reste-t-il des chunks ?
    ///\return Chunk restant
    inline bool has_next(){
      return it!=block_lst.end();
    }

    inline unsigned int getCurrentWidth(int type){
      return type==IN? (*it).wblock_in : (*it).wblock_out ;
    }

    inline unsigned int getCurrentHeight(int type){
      return type==IN? (*it).hblock_in : (*it).hblock_out ;
    }

    inline unsigned int getMaxWidth(int type){
      return type==IN? wblock_in : wblockmax_out;
    }

    inline unsigned int getMaxHeight(int type){
      return type==IN? hblock_in : hblockmax_out;
    }

    inline coord_data current(){
      return (*it);
    }
  };

}
#endif
